package com.smarttest.portal.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI;
import br.eti.kinoshita.testlinkjavaapi.constants.ActionOnDuplicate;
import br.eti.kinoshita.testlinkjavaapi.constants.ExecutionType;
import br.eti.kinoshita.testlinkjavaapi.constants.TestCaseStatus;
import br.eti.kinoshita.testlinkjavaapi.constants.TestImportance;
import br.eti.kinoshita.testlinkjavaapi.model.CustomField;
import br.eti.kinoshita.testlinkjavaapi.model.TestCase;
import br.eti.kinoshita.testlinkjavaapi.model.TestCaseStep;

import com.g7s.test.utils.Excel.DataHandlers;
import com.g7s.test.utils.common.JdbcUtils;
import com.smarttest.portal.service.FileService;

@Service
public class FileServiceImpl implements FileService {
	@Value("${FTP_BASE_PATH}")
	private String FTP_BASE_PATH;
	private final String sql_getUsers = "select t1.login from testlink.`users` t1 left join (SELECT user_id FROM testlink.`user_testproject_roles` where testproject_id = ? and role_id in (1,2,3,5,11))t2 on t1.id = t2.user_id where t2.user_id is null and t1.role_id>3 and t1.role_id != 5 and t1.role_id != 11"
			+ "union SELECT user_id FROM testlink.`user_testproject_roles` where testproject_id = ? and role_id  not in (1,2,3,5,11);";
	private final String sql_getSuiteId = "SELECT * FROM testlink.`nodes_hierarchy` where parent_id = ? and node_type_id = 2 and name = ?;";
	@Value("${FTP_CASE_PATH}")
	private String FTP_CASE_PATH;
	@Value("${FTP_MQ_PATH}")
	private String FTP_MQ_PATH;
	// private static JdbcUtils jdbc = new JdbcUtils("com.mysql.jdbc.Driver",
	// "jdbc:mysql://172.22.35.240:3306?zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&useUnicode=true&characterEncoding=UTF-8",
	// "root", "Huoyunren1@");
	@Value("${FTP_EXCELCASE_PATH}")
	private String FTP_EXCELCASE_PATH;

	@Override
	public int uploadFile(MultipartFile uploadFile) {
		try {
			// 取原始文件名
			String filename = uploadFile.getOriginalFilename();
			// 文件上传
			SaveFileFromInputStream(uploadFile.getInputStream(), filename);
			return 200;
		} catch (IOException e) {
			e.printStackTrace();
			return 500;
		} catch (Exception e) {
			e.printStackTrace();
			return 500;
		}
	}

	@Override
	public int uploadFileWithUser(String userName, MultipartFile uploadFile) {
		try {
			// 取原始文件名
			String filename = uploadFile.getOriginalFilename();
			// 文件上传
			SaveFileFromInputStream(uploadFile.getInputStream(), userName + filename);
			return 200;
		} catch (IOException e) {
			e.printStackTrace();
			return 500;
		} catch (Exception e) {
			e.printStackTrace();
			return 500;
		}
	}

	@Override
	public int importcase(TestLinkAPI api, int projectid, String userName, String sheetname, String filename) {
		// try {
		// List<Object> params = new ArrayList<Object>();
		// params.add(projectid);
		// List<Map<String, Object>> ls = jdbc.findModeResult(sql_getUsers,
		// params);
		// Set<String> s = new HashSet<>();
		// for (int i = 0; i < ls.size(); i++) {
		// s.add(ls.get(i).get("login").toString());
		// }
		// if(!s.contains(userName)) {
		// return 201;
		// }
		// importcaseTotestlink(api,projectid,userName,filename,sheetname);
		// return 200;
		// } catch(Exception e){
		// e.printStackTrace();
		// return 500;
		// }
		return 201;
	}

	private int getSuiteIdFromParentNode(TestLinkAPI api, int proid, int parentid, String suitename) {
		// List<Object> params = new ArrayList<Object>();
		// if (parentid == -1) {
		// params.add(proid);
		// }
		// else {
		// params.add(parentid);
		// }
		// params.add(suitename);
		// int id = -1;
		// try {
		// List<Map<String, Object>> ls = jdbc.findModeResult(sql_getSuiteId,
		// params);
		// if (ls.size() == 0) {
		// if (parentid == -1) {
		// id = api.createTestSuite(proid, suitename, "", null, null, true,
		// ActionOnDuplicate.GENERATE_NEW).getId();
		// }
		// else {
		// id = api.createTestSuite(proid, suitename, "", parentid, null, true,
		// ActionOnDuplicate.GENERATE_NEW).getId();
		// }
		// }
		// else {
		// id = new Integer(String.valueOf(ls.get(0).get("id")));
		// }
		// } catch (SQLException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		return 1;
	}

	private void importcaseTotestlink(TestLinkAPI api, int projectid, String userName, String filename,
			String sheetname) {
		// TODO Auto-generated method stub
		DataHandlers excelhandler = DataHandlers.getInstance(filename);
		Object[][] datas = excelhandler.getData(sheetname);
		for (int i = 1; i < datas.length; i++) {
			String module = datas[i][0].toString();
			List<String> modulesList = Arrays.asList(module.split("/"));
			for (String s : modulesList) {
				if (s.isEmpty()) {
					modulesList.remove(s);
				}
			}
			int tmpsuiteid = -1;
			for (int k = 0; k < modulesList.size(); k++) {
				tmpsuiteid = getSuiteIdFromParentNode(api, projectid, tmpsuiteid, modulesList.get(k));
			}
			String casename = datas[i][1].toString();
			String summury = datas[i][2].toString();
			if (summury.isEmpty()) {
				summury = casename;
			}
			String importance = datas[i][4].toString();
			TestImportance testimportance = TestImportance.MEDIUM;
			//重要程度
			if (importance.equalsIgnoreCase("HIGH") || importance.equals("1") || importance.equals("高")) {
				testimportance = TestImportance.HIGH;
			} else if (importance.equalsIgnoreCase("low") || importance.equals("3") || importance.equals("低")) {
				testimportance = TestImportance.LOW;
			}
			String preconditions = datas[i][5].toString();
			String teststeps = datas[i][6].toString();
			String expectresults = datas[i][7].toString();
			String testtype = datas[i][8].toString();
			ExecutionType test_type = ExecutionType.MANUAL;
			//测试类型；自动或者手动
			if (testtype.equalsIgnoreCase("AUTOMATED") || testtype.contains("自动") || testtype.equals("2")) {
				test_type = ExecutionType.AUTOMATED;
			}
			String customfields = datas[i][9].toString();
			String[] fields = customfields.split("\n");
			List<CustomField> fieldlist = new ArrayList<CustomField>();
			for (int j = 0; j < fields.length; j++) {
				String[] field_str = fields[j].split("\\:");
				CustomField field = new CustomField();
				field.setName(field_str[0]);
				field.setValue(field_str[1]);
				fieldlist.add(field);
			}
			String keywords = datas[i][10].toString();
			List<String> keywordslist = Arrays.asList(keywords.split(";"));
			// String attachment = datas[i][11].toString();
			List<TestCaseStep> steps = new ArrayList<TestCaseStep>();
			String stepsarray[] = teststeps.split("\n");
			String expectresultsarray[] = expectresults.split("\n");
			if (expectresultsarray.length > stepsarray.length) {
				try {
					throw new Exception("预期数不能大于步骤数");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			for (int j = 0; j < stepsarray.length; j++) {
				//添加步骤
				steps.add(new TestCaseStep(null, null, j + 1, stepsarray[j], expectresultsarray[j], true, test_type));
			}
			TestCase c = api.createTestCase(casename, tmpsuiteid, projectid, userName, summury, steps, preconditions,
					TestCaseStatus.DRAFT, testimportance, test_type, null, null, true, ActionOnDuplicate.GENERATE_NEW);
			//custom field
			c.setCustomFields(fieldlist);
			//关键字
			c.setKeywords(keywordslist);
			Map<String, Object> m = api.updateTestCase(c);
			for (int j = 0; j < fields.length; j++) {
				String[] field_str = fields[j].split("\\:");
				api.updateTestCaseCustomFieldDesignValue(c.getId(), 1, projectid, field_str[0], field_str[1]);
			}
			// api.uploadTestCaseAttachment(c.getId(), attachment.split(";")[0],
			// null, attachment.split(";")[1], "txt", "sadasdasd");
		}
	}
	/**
	 * zip包解压
	 */
	public List<String> zipDecompressing(File file) {
		List<String> returnFiles = new ArrayList<String>();
		try {
			returnFiles = unZipFiles(file);
			return returnFiles;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return returnFiles;
	}
	/**
	 * 文件流输出到文件
	 * @param stream
	 * @param filename
	 * @throws IOException
	 */
	private void SaveFileFromInputStream(InputStream stream, String filename) throws IOException {
		File file = new File(FTP_BASE_PATH);
		File[] files = file.listFiles();
		if (files != null && files.length > 0) {
			for (File filetemp : files) {
				if (filetemp.getName().equals(filename)) {
					filetemp.delete();
				}
			}
		}
		FileOutputStream fs = new FileOutputStream(FTP_BASE_PATH + "//" + filename);
		byte[] buffer = new byte[1024 * 1024];
		int bytesum = 0;
		int byteread = 0;
		while ((byteread = stream.read(buffer)) != -1) {
			bytesum += byteread;
			fs.write(buffer, 0, byteread);
			fs.flush();
		}
		fs.close();
		stream.close();
	}
	/**
	 * 文件流输出到指定目录的某个文件
	 * @param folderpath
	 * @param stream
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	private String SaveFileFromInputStream(String folderpath, InputStream stream, String filename) throws Exception {
		File file = new File(folderpath);
		file.mkdir();
		if (!file.exists() || !file.isDirectory()) {
			throw new Exception();
		}
		File[] files = file.listFiles();
		for (File filetemp : files) {
			if (filetemp.getName().equals(filename)) {
				filetemp.delete();
			}
		}
		String actualfile = folderpath + filename;
		FileOutputStream fs = new FileOutputStream(actualfile);
		byte[] buffer = new byte[1024 * 1024];
		int bytesum = 0;
		int byteread = 0;
		while ((byteread = stream.read(buffer)) != -1) {
			bytesum += byteread;
			fs.write(buffer, 0, byteread);
			fs.flush();
		}
		fs.close();
		return actualfile;
	}
	private List<String> unZipFiles(File input) throws IOException {
		ZipFile zip = new ZipFile(input);
		List<String> fileNames = new ArrayList<String>();
		for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
			ZipEntry entry = (ZipEntry) entries.nextElement();
			String zipEntryName = entry.getName();
			InputStream in = zip.getInputStream(entry);
			String outPath = (FTP_BASE_PATH + "//" + zipEntryName).replaceAll("\\*", "/");
			;
			// 判断路径是否存在,不存在则创建文件路径
			File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
			if (!file.exists()) {
				file.mkdirs();
			}
			// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
			if (new File(outPath).isDirectory()) {
				continue;
			}
			OutputStream out = new FileOutputStream(outPath);
			// 这里加入list逻辑
			fileNames.add(outPath);
			byte[] buf1 = new byte[1024];
			int len;
			while ((len = in.read(buf1)) > 0) {
				out.write(buf1, 0, len);
			}
			in.close();
			out.close();
		}
		System.out.println("******************解压完毕********************");
		return fileNames;
	}

	@Override
	public Object uploadCaseWithUser(String userName, MultipartFile uploadFile) {
		// TODO Auto-generated method stub
		try {
			// 取原始文件名
			String filename = uploadFile.getOriginalFilename();
			// 文件上传
			InputStream in = uploadFile.getInputStream();
			String outputfile = SaveFileFromInputStream(FTP_CASE_PATH, in, userName + filename);
			in.close();
			return outputfile;
		} catch (IOException e) {
			e.printStackTrace();
			return 500;
		} catch (Exception e) {
			e.printStackTrace();
			return 500;
		}
	}

	@Override
	public Object uploadMQWithUser(String userName, MultipartFile uploadFile) {
		// TODO Auto-generated method stub
		try {
			// 取原始文件名
			String filename = uploadFile.getOriginalFilename();
			// 文件上传
			InputStream in = uploadFile.getInputStream();
			String outputfile = SaveFileFromInputStream(FTP_MQ_PATH, in, userName + filename);
			in.close();
			return outputfile;
		} catch (IOException e) {
			e.printStackTrace();
			return 500;
		} catch (Exception e) {
			e.printStackTrace();
			return 500;
		}
	}

	@Override
	public Object uploadExcelCaseWithUser(String userName, MultipartFile[] uploadFiles) {
		// TODO Auto-generated method stub
		List<String> filelist = new ArrayList<String>();
		try {
			// 取原始文件名
			for (MultipartFile uploadFile : uploadFiles) {
				String filename = uploadFile.getOriginalFilename();
				// 文件上传
				InputStream in = uploadFile.getInputStream();
				String outputfile = SaveFileFromInputStream(FTP_EXCELCASE_PATH, in, userName + filename);
				in.close();
				filelist.add(outputfile);
			}
			return filelist;
		} catch (IOException e) {
			e.printStackTrace();
			return 500;
		} catch (Exception e) {
			e.printStackTrace();
			return 500;
		}
	}
}
